package org.yellow.backend.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.yellow.backend.mapper.UserMapper;
import org.yellow.backend.mapper.patientMapper;
import org.yellow.backend.pojo.LoginUser;
import org.yellow.backend.pojo.ResponseResult;
import org.yellow.backend.pojo.User;
import org.yellow.backend.pojo.patient;
import org.yellow.backend.service.LoginService;
import org.yellow.backend.utility.patientStatus;
import org.yellow.backend.utils.JwtUtil;
import org.yellow.backend.utils.RedisCache;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserMapper userMapper;


    @Autowired
    private RedisCache redisCache;

    @Override
    public ResponseResult login(User user) {

        //AuthenticationManager.authenticate进行用户认证
        //传入账号密码封装成Authentication对象
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(),user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        //认证没通过给出提示
        if (Objects.isNull(authenticate)){
            throw new RuntimeException("登录失败");
        }
        //通过则使用userid生成一个jwt，jwt存入ResponseResult返回
        LoginUser loginUser = (LoginUser)authenticate.getPrincipal();
        String userid = loginUser.getUser().getId().toString();
        String jwt = JwtUtil.createJWT(userid);//生成jwt

        Map<String,String> map = new HashMap<>();
        map.put("token",jwt);
        if (userMapper.existPatient(user.getUserName())!=0){//是病人
            int patientId = userMapper.findPatientIDByUserName(user.getUserName());
            map.put("patientId", String.valueOf(patientId));
            map.put("doctorId","-1");
        } else{//是医生
            map.put("patientId","-1");
            int doctorId = userMapper.findDoctorIDByUserName(user.getUserName());
            map.put("doctorId", String.valueOf(doctorId));
            map.put("patientId","-1");
        }
        //把完整的用户信息存入redis，userid作为key
        redisCache.setCacheObject("login:"+userid,loginUser);
        return new ResponseResult(200,"登录成功",map);
    }

    @Override
    public ResponseResult logout() {
        //获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long userid = loginUser.getUser().getId();
        //删除redis中的值
        redisCache.deleteObject("login:"+userid);
        return new ResponseResult(200,"注销成功");
    }

    @Autowired
    private patientMapper patientMapper;

    @Override
    public ResponseResult register(User user) {
        //密码加密存储
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        patient patient = new patient();
        patient.setPassword(user.getPassword());
        user.setPassword(passwordEncoder.encode(user.getPassword()));

        //存储病人

        patient.setStatus(patientStatus.Active);
        patient.setGender(user.getSex());
        patient.setContactNumber(user.getPhonenumber());
        patient.setName(user.getNickName());
        patient.setUserName(user.getUserName());
        patientMapper.insert(patient);

        //存储账号和角色
        int ans = userMapper.register(user);
        Long userid = user.getId();
        userMapper.setRole(userid,2);
        return new ResponseResult(200,"注册成功");
    }

    @Override
    public ResponseResult update(User user) {
        //密码加密存储
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        user.setPassword(passwordEncoder.encode(user.getPassword()));

        userMapper.update(user);
        return new ResponseResult(200,"修改成功");
    }
}
